using Jupiter.Infrastructure.Attributes;
using Jupiter.Infrastructure.Cache.Interfaces;
using Jupiter.Infrastructure.Domain.SqlSugar;
using Jupiter.Infrastructure.Permission;
using Jupiter.Infrastructure.Permission.DataPermissions;
using Jupiter.Infrastructure.Responses;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Localization;
using Wips.AppService.Authorities.Menus;
using Wips.AppService.Authorities.Menus.Requests;
using Wips.AppService.Authorities.Menus.Responses;
using Wips.AppService.Authorities.Menus.ViewModels;
using Wips.AppService.CommonViewModels;
using Wips.Domain.Models.Authorities.Model;

namespace Wips.AppService.SqlSugar.Authorities.Menus
{
    /// <summary>
    /// 菜单服务接口实现类
    /// </summary>
    [ServiceComponent]
    public class MenuService : BaseQueryAppService<Menu>, IMenuService
    {
        public MenuService(ISqlSugarClient dbContext, ISecurityContextAccessor securityContextAccessor,
            IConfiguration? configuration, ICacheManager cacheManager, IDataPermission? dataPermission,
            IStringLocalizer? localizer) : base(dbContext, securityContextAccessor, configuration, cacheManager,
            dataPermission, localizer)
        {
        }

        /// <summary>
        /// 读取分页列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<PageResult<GetMenuPagesResponse>> GetPagesAsync(
            GetMenuPagesRequest request)
        {
            return await QueryNoTracking()
                .Select(p => new GetMenuPagesResponse
                {
                    Id = p.Id!,
                    Created = p.Created,
                    Name = p.Name,
                    Icon = p.Icon,
                    Path = p.Path,
                    Status = p.Status,
                    Updated = p.Updated,
                    ParentId = p.ParentId,
                    IsInside = p.IsInside
                })
                .ToPageAsync(request);
        }

        /// <summary>
        /// 读取信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<MenuViewModel> GetByIdAsync(string id)
        {
            return await QueryNoTracking()
                .Where(p => p.Id == id)
                .Select(p => new MenuViewModel
                {
                    Id = p.Id!,
                    Name = p.Name,
                    Path = p.Path,
                    Icon = p.Icon,
                    Status = p.Status,
                    ParentId = p.ParentId,
                    Sort = p.Sort,
                    IsInside = p.IsInside
                })
                .FirstOrDefaultAsync();
        }

        /// <summary>
        /// 读取树形数据
        /// </summary>
        /// <returns></returns>
        public async Task<List<GetMenuTreeDataResponse>> GetTreeDataAsync()
        {
            var list = await QueryNoTracking()
                .Includes(c => c.Operations)
                .ToListAsync();

            // 读取菜单的操作列表
            var operations = new List<Operation>();
            if (list.Count > 0)
            {
                operations = list.SelectMany(c => c.Operations).ToList();
            }

            var result = new List<GetMenuTreeDataResponse>();
            // 递归读取
            GetTreeChildren(list, result, operations, "");
            return result;
        }

        /// <summary>
        /// 读取树形选择框数据列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<TreeSelectViewModel>> GetTreeSelectDataAsync()
        {
            var list = await QueryNoTracking()
                .ToListAsync();

            var result = new List<TreeSelectViewModel>();
            // 递归读取
            GetTreeChildrenBySelect(list, result, "");
            return result;
        }


        /// <summary>
        /// 读取树形选择框数据列表
        /// </summary>
        /// <param name="roleId">角色Id</param>
        /// <returns></returns>
        public async Task<GetTreeSelectDataByRoleIdResponse> GetTreeSelectDataByRoleIdAsync(
            string roleId)
        {
            var list = await QueryNoTracking()
                .ToListAsync();

            // 操作列表
            var operations = await QueryNoTracking<Operation>()
                .ToListAsync();


            // 菜单权限
            var permissionMenuIds = await QueryNoTracking<PermissionMenu>()
                .InnerJoin<RolePermission>(
                    (menu, per) => menu.PermissionId == per.PermissionId
                )
                .Where((menu, per) => per.RoleId == roleId)
                .Select(menu => menu.MenuId)
                .ToListAsync();

            // 操作权限
            var permissionOperationIds = await QueryNoTracking<PermissionOperation>()
                .InnerJoin<RolePermission>(
                    (menu, per) => menu.PermissionId == per.PermissionId
                )
                .Where((menu, per) => per.RoleId == roleId)
                .Select(menu => menu.OperationId)
                .ToListAsync();

            var result = new List<GetTreeSelectDataByRoleIdInfo>();
            var checkedKeys = new List<string>();
            // 递归读取
            GetTreeChildrenBySelect(
                list, result, checkedKeys, operations,
                permissionMenuIds, permissionOperationIds,
                ""
            );

            return new GetTreeSelectDataByRoleIdResponse(result, checkedKeys);
        }


        /// <summary>
        /// 读取树形表格数据
        /// </summary>
        /// <returns></returns>
        public async Task<GetTreeTableResponse> GetTreeTableByRoleIdAsync(string roleId)
        {
            // 读取权限
            var (permissionMenuIds, permissionOperationIds) = await GetPermissionIdsByRoleIdAsync(roleId);
            var tList = await QueryNoTracking<Menu>().Includes(c => c.Operations)
                .ToListAsync();
            var list = tList.Select(c => c).ToList();


            var result = new List<TreeTableModel>();
            var menuCheckedKeys = new List<string>();
            var operationCheckedKeys = new List<string>();
            // 递归读取
            GetTreeTableChildren(
                list,
                result,
                menuCheckedKeys,
                operationCheckedKeys,
                permissionMenuIds,
                permissionOperationIds
            );
            return new GetTreeTableResponse(result, menuCheckedKeys, operationCheckedKeys);
        }


        /// <summary>
        /// 读取树形表格数据
        /// </summary>
        /// <returns></returns>
        public async Task<GetTreeTableResponse> GetTreeTableByVersionsIdAsync(string versionId)
        {
            var list = await QueryNoTracking()
                .Includes(c => c.Operations)
                .ToListAsync();

            // 读取权限
            var (permissionMenuIds, permissionOperationIds) = await GetPermissionIdsByVersionIdAsync(versionId);

            var result = new List<TreeTableModel>();
            var menuCheckedKeys = new List<string>();
            var operationCheckedKeys = new List<string>();
            // 递归读取
            GetTreeTableChildren(
                list,
                result,
                menuCheckedKeys,
                operationCheckedKeys,
                permissionMenuIds,
                permissionOperationIds
            );
            return new GetTreeTableResponse(result, menuCheckedKeys, operationCheckedKeys);
        }


        /// <summary>
        /// 读取树形菜单列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<TreeMenuViewModel>> GetTreeMenuByUserIdAsync()
        {
            // 读取菜单列表
            List<MenuViewModel> list;
            if (UserName == "root")
            {
                list = await GetRootVersionMenusAsync();
            }
            else
            {
                list = await GetVersionsMenusAsync(UserId!);
            }

            // 结果集
            var result = new List<TreeMenuViewModel>();
            // 递归读取
            GetTreeMenuChildren(list, result, "");
            return result;
        }

        /// <summary>
        /// 获取用户路由
        /// </summary>
        /// <returns></returns>
        public async Task<List<MenuItemViewModel>> GetUserRoutesAsync()
        {
            // List<MenuItemViewModel> result = new List<MenuItemViewModel>();


            // 读取菜单列表
            List<MenuViewModel> list;
            if (UserName == "root")
            {
                list = await GetRootVersionMenusAsync();
            }
            else
            {
                list = await GetVersionsMenusAsync(UserId!);
            }

            // 结果集
            var result = new List<TreeMenuViewModel>();
            // 递归读取
            GetTreeMenuChildren(list, result, "");

            // 处理应用数据
            var appList = new List<MenuItemViewModel>()
            {
                new()
                {
                    Name = "运维中心",
                    Path = "",
                    MicroApp = "'",
                    Children = new List<MenuItemViewModel>(),
                    Routes = new List<MenuItemViewModel>(),
                    HideInMenu = true
                }
            };
            // 处理菜单数据


            var appRe = list.ToList();
            MapTreeMenuChildren(appRe, appList, null);


            foreach (var app in appList)
            {
                // 顶级目录如果为空，需要找到第一个不为空的路由，否则前端会跳转不了
                if (!app.HideInMenu && (app.Path == "/" || string.IsNullOrEmpty(app.Path)))
                {
                    app.Path = GetFirstChildPath(app.Children);
                }
            }

            return appList.Where(c => c.Children.Count > 0).ToList();
        }


        /// <summary>
        /// 获取第一个有效的path
        /// </summary>
        /// <param name="children"></param>
        /// <returns></returns>
        private string GetFirstChildPath(List<MenuItemViewModel> children)
        {
            foreach (var c in children)
            {
                if (c.Path != "/" && !string.IsNullOrEmpty(c.Path))
                {
                    return c.Path!;
                }

                return GetFirstChildPath(c.Children);
            }

            return "/";
        }


        /// <summary>
        /// 读取菜单权限
        /// </summary>
        /// <param name="userId">用户Id，默认为当前登录用户</param>
        /// <param name="versionIds">应用版本</param>
        /// <param name="isRoot"></param>
        /// <returns></returns>
        public async Task<List<MenuViewModel>> GetRoutePathAsync(string? userId,
            bool isRoot = false)
        {
            // 读取菜单列表
            List<MenuViewModel> list;
            if (isRoot)
                list = await GetRootVersionMenusAsync();
            else
                list = await GetVersionsMenusAsync(userId!);

            if (list.Count == 0)
            {
                return list;
            }

            // 需要读取菜单的上级菜单
            var parentResult = await QueryNoTracking()
                .Where(p => list.Select(c => c.ParentId).Distinct().Contains(p.Id))
                .Select(p => new
                {
                    p.Id,
                    p.Path
                })
                .ToListAsync();

            foreach (var item in list)
            {
                item.ParentPath = parentResult.FirstOrDefault(c => c.Id == item.ParentId)?.Path;
            }

            return list;
        }


        #region 私有方法

        /// <summary>
        /// 根据用户版本读取菜单
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="versionIds"></param>
        /// <returns></returns>
        private async Task<List<MenuViewModel>> GetVersionsMenusAsync(string userId)
        {
            var roleIdSql = await GetUserRoleSql(userId);

            var list = await QueryNoTracking<Permission>()
                .InnerJoin<PermissionMenu>((pe, pm) => pe.Id == pm.PermissionId && pm.Menu.Status == Status.Enabled)
                .InnerJoin<RolePermission>((pe, pm, rp) =>
                    roleIdSql!.Contains(rp.RoleId)
                )
                .InnerJoin<Permission>((pe, pm, rp, rpp) => rpp.Id == rp.PermissionId)
                .InnerJoin<PermissionMenu>((pe, pm, rp, rpp, rpm) =>
                    rpm.PermissionId == rpp.Id && pm.MenuId == rpm.MenuId)
                .Where(pe => pe.PermissionType == AuthoritiePermissionType.Menu)
                .OrderBy((pe, pm) => pm.Menu.Sort)
                .Select((pe, pm) => new MenuViewModel()
                {
                    Id = pm.MenuId,
                    Name = pm.Menu.Name,
                    Path = pm.Menu.Path,
                    ParentId = pm.Menu.ParentId,
                    Status = pm.Menu.Status,
                    Sort = pm.Menu.Sort,
                    Icon = pm.Menu.Icon,
                    IsInside = pm.Menu.IsInside
                })
                .ToListAsync();
            return list.GroupBy(c => new
                {
                    c.Path,
                    c.Id,
                    c.Name,
                    c.ParentId,
                    c.Status,
                    c.Sort,
                    c.Icon,
                    c.IsInside,
                })
                .Select(c => new MenuViewModel
                {
                    Id = c.Key.Id,
                    Name = c.Key.Name,
                    Path = c.Key.Path,
                    ParentId = c.Key.ParentId,
                    Status = c.Key.Status,
                    Sort = c.Key.Sort,
                    Icon = c.Key.Icon,
                    IsInside = c.Key.IsInside
                }).ToList();
        }

        /// <summary>
        /// 查询root账户菜单
        /// </summary>
        /// <returns></returns>
        private async Task<List<MenuViewModel>> GetRootVersionMenusAsync()
        {
            var list = await QueryNoTracking<Menu>()
                .OrderBy(me => me.Sort)
                .Select(me => new MenuViewModel()
                {
                    Id = me.Id,
                    Name = me.Name,
                    Path = me.Path,
                    ParentId = me.ParentId,
                    Status = me.Status,
                    Sort = me.Sort,
                    Icon = me.Icon,
                    IsInside = me.IsInside
                })
                .ToListAsync();
            return list.GroupBy(c => new
                {
                    c.Path,
                    c.Id,
                    c.Name,
                    c.ParentId,
                    c.Status,
                    c.Sort,
                    c.Icon,
                    c.IsInside
                })
                .Select(c => new MenuViewModel
                {
                    Id = c.Key.Id,
                    Name = c.Key.Name,
                    Path = c.Key.Path,
                    ParentId = c.Key.ParentId,
                    Status = c.Key.Status,
                    Sort = c.Key.Sort,
                    Icon = c.Key.Icon,
                    IsInside = c.Key.IsInside
                }).ToList();
        }

        /// <summary>
        /// 递归读取
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="results"></param>
        /// <param name="parentId"></param>
        private static void GetTreeMenuChildren(
            IList<MenuViewModel> entities,
            ICollection<TreeMenuViewModel> results,
            string? parentId = null
        )
        {
            IList<MenuViewModel> result = string.IsNullOrEmpty(parentId)
                ? entities.Where(p => string.IsNullOrEmpty(p.ParentId)).ToList()
                : entities.Where(p => p.ParentId == parentId).ToList();

            foreach (var item in result)
            {
                var res = new TreeMenuViewModel
                {
                    Id = item.Id!,
                    ParentId = item.ParentId,
                    Key = item.Id,
                    Name = item.Name,
                    Path = item.Path,
                    Sort = item.Sort,
                    Title = item.Name,
                    Value = item.Id!,
                    IsInside = item.IsInside
                };
                if (entities.Any(p => p.ParentId == item.Id))
                {
                    res.Children = new List<TreeMenuViewModel>();
                    GetTreeMenuChildren(entities, res.Children, item.Id);
                }

                results.Add(res);
            }
        }


        /// <summary>
        /// 递归读取
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="results"></param>
        /// <param name="app"></param>
        /// <param name="parent"></param>
        private static void MapTreeMenuChildren(
            IList<MenuViewModel> entities,
            ICollection<MenuItemViewModel> results,
            MenuItemViewModel? parent = null
        )
        {
            IList<MenuViewModel> result = string.IsNullOrEmpty(parent?.Key)
                ? entities.Where(p => string.IsNullOrEmpty(p.ParentId)).ToList()
                : entities.Where(p => p.ParentId == parent.Key).ToList();

            foreach (var item in result)
            {
                var aPath = "";
                var microApp = "";

                aPath = parent == null ? item.Path : parent.Path + item.Path;
                microApp = null;


                var res = new MenuItemViewModel
                {
                    MicroApp = microApp,
                    ParentId = item.ParentId,
                    Key = item.Id!,
                    Name = item.Name,
                    Path = aPath,
                    Icon = item.Icon,
                    HideInMenu = !item.IsInside,
                    HideChildrenInMenu = !item.IsInside,
                    Sort = item.Sort,
                };
                res.Routes = new List<MenuItemViewModel>();

                if (entities.Any(p => p.ParentId == item.Id))
                {
                    MapTreeMenuChildren(entities, res.Routes, res);
                    res.Children = res.Routes;
                }

                results.Add(res);
            }
        }

        /// <summary>
        /// 递归读取
        /// </summary>
        /// <param name="entities">菜单列表</param>
        /// <param name="results">结果集</param>
        /// <param name="checkedKeys">结果集</param>
        /// <param name="operations">操作列表</param>
        /// <param name="permissionMenuIds">菜单权限</param>
        /// <param name="permissionOperationIds">操作权限</param>
        /// <param name="parentId">父级Id</param>
        private static void GetTreeChildrenBySelect(IList<Menu> entities,
            ICollection<GetTreeSelectDataByRoleIdInfo> results,
            ICollection<string> checkedKeys,
            IReadOnlyList<Operation> operations,
            IReadOnlyList<string> permissionMenuIds,
            IReadOnlyList<string> permissionOperationIds,
            string? parentId = null)
        {
            IList<Menu> result = string.IsNullOrEmpty(parentId)
                ? entities.Where(p => string.IsNullOrEmpty(p.ParentId)).ToList()
                : entities.Where(p => p.ParentId == parentId).ToList();

            foreach (var t1 in result)
            {
                // 菜单权限
                var isMenuChecked = permissionMenuIds.Any(menuId => menuId == t1.Id);
                var res = new GetTreeSelectDataByRoleIdInfo
                {
                    Id = t1.Id,
                    ParentId = t1.ParentId,
                    Title = t1.Name,
                    Value = t1.Id,
                    Key = t1.Id,
                    Disabled = t1.Status == Status.Disabled,
                    IsLeaf = true,
                    Type = 1,
                    Checked = isMenuChecked
                };
                // 如果菜单下有操作
                var operationList = operations.Where(p => p.MenuId == t1.Id).ToList();

                // 如果没有子项才添加
                if (isMenuChecked && entities.All(p => p.ParentId != t1.Id) && !operationList.Any())
                {
                    checkedKeys.Add(t1.Id!);
                }

                // 如果菜单下有操作或者菜单下有子菜单
                if (operationList.Any() || entities.Any(p => p.ParentId == t1.Id))
                {
                    res.IsLeaf = false;
                    res.Checked = false;
                    res.Children = new List<GetTreeSelectDataByRoleIdInfo>();

                    // 处理操作
                    if (operationList.Any())
                    {
                        foreach (var item in operationList)
                        {
                            // 操作权限
                            var isOperationChecked =
                                permissionOperationIds.Any(operationId => operationId == item.Id);

                            if (isOperationChecked)
                            {
                                checkedKeys.Add(item.Id!);
                            }

                            res.Children.Add(new GetTreeSelectDataByRoleIdInfo
                            {
                                Id = item.Id,
                                ParentId = t1.Id,
                                Title = item.Name,
                                Value = item.Id,
                                Key = item.Id,
                                IsLeaf = true,
                                Type = 2,
                                Checked = isOperationChecked
                            });
                        }
                    }

                    // 处理菜单
                    if (entities.Any(p => p.ParentId == t1.Id))
                    {
                        GetTreeChildrenBySelect(
                            entities,
                            res.Children,
                            checkedKeys,
                            operations,
                            permissionMenuIds,
                            permissionOperationIds,
                            t1.Id
                        );
                    }
                }

                results.Add(res);
            }
        }

        /// <summary>
        /// 递归读取
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="results"></param>
        /// <param name="parentId"></param>
        private static void GetTreeChildrenBySelect(IList<Menu> entities,
            ICollection<TreeSelectViewModel> results,
            string? parentId = null)
        {
            IList<Menu> result = string.IsNullOrEmpty(parentId)
                ? entities.Where(p => string.IsNullOrEmpty(p.ParentId)).ToList()
                : entities.Where(p => p.ParentId == parentId).ToList();

            foreach (var t1 in result)
            {
                var res = new TreeSelectViewModel
                {
                    Id = t1.Id,
                    ParentId = t1.ParentId,
                    Title = t1.Name,
                    Value = t1.Id,
                    Key = t1.Id,
                    Disabled = t1.Status == Status.Disabled,
                    IsLeaf = true,
                };
                if (entities.Any(p => p.ParentId == t1.Id))
                {
                    res.IsLeaf = false;
                    res.Children = new List<TreeSelectViewModel>();
                    GetTreeChildrenBySelect(entities, res.Children, t1.Id);
                }

                results.Add(res);
            }
        }

        /// <summary>
        /// 递归读取
        /// </summary>
        /// <param name="entities">菜单数据源</param>
        /// <param name="results">结果集</param>
        /// <param name="operations">操作数据源</param>
        /// <param name="parentId"></param>
        private static void GetTreeChildren(IList<Menu> entities,
            ICollection<GetMenuTreeDataResponse> results,
            IReadOnlyCollection<Operation> operations,
            string? parentId = null)
        {
            IList<Menu> result = string.IsNullOrEmpty(parentId)
                ? entities.Where(p => string.IsNullOrEmpty(p.ParentId)).ToList()
                : entities.Where(p => p.ParentId == parentId).ToList();

            foreach (var item in result)
            {
                var res = new GetMenuTreeDataResponse
                {
                    Id = item.Id!,
                    Key = item.Id!,
                    ParentId = item.ParentId,
                    Name = item.Name,
                    Icon = item.Icon,
                    Path = item.Path,
                    Sort = item.Sort,
                    IsInside = item.IsInside,
                    Status = item.Status,
                    Created = item.Created,
                    Updated = item.Updated,
                    MenuType = "菜单",
                    Operations = operations
                        .Where(p => p.MenuId == item.Id)
                        .OrderBy(p => p.Sort)
                        .Select(p => new SelectViewModel
                        {
                            Label = p.Name,
                            Value = p.Id!
                        })
                        .ToList()
                };
                if (entities.Any(p => p.ParentId == item.Id))
                {
                    res.MenuType = "目录";
                    res.Children = new List<GetMenuTreeDataResponse>();
                    GetTreeChildren(entities, res.Children, operations, item.Id);
                }

                results.Add(res);
            }
        }


        /// <summary>
        /// 读取权限ID列表  by versionId
        /// </summary>
        /// <param name="versionId"></param>
        /// <returns></returns>
        private async Task<(List<string> permissionMenuIds, List<string> permissionOperationIds)>
            GetPermissionIdsByVersionIdAsync(string versionId)
        {
            // 菜单权限
            var permissionMenuIds = await QueryNoTracking<PermissionMenu>()
                .Select(p => p.MenuId)
                .ToListAsync();

            // 操作权限
            var permissionOperationIds = await QueryNoTracking<PermissionOperation>()
                .Select(p => p.OperationId)
                .ToListAsync();
            return (permissionMenuIds, permissionOperationIds);
        }


        /// <summary>
        /// 读取权限ID列表 by roleId
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        private async Task<(List<string> permissionMenuIds, List<string> permissionOperationIds)>
            GetPermissionIdsByRoleIdAsync(string roleId)
        {
            // 菜单权限
            var permissionMenuIds = await QueryNoTracking<PermissionMenu>()
                .Where(p => p.PermissionId == SqlFunc.Subqueryable<RolePermission>()
                    .Where(c => c.RoleId == roleId)
                    .GroupBy(c => c.PermissionId)
                    .Select(c => c.PermissionId))
                .Select(p => p.MenuId)
                .ToListAsync();

            // 操作权限
            var permissionOperationIds = await QueryNoTracking<PermissionOperation>()
                .Where(p => p.PermissionId == SqlFunc.Subqueryable<RolePermission>()
                    .Where(c => c.RoleId == roleId)
                    .GroupBy(c => c.PermissionId)
                    .Select(c => c.PermissionId))
                .Select(p => p.OperationId)
                .ToListAsync();
            return (permissionMenuIds, permissionOperationIds);
        }


        /// <summary>
        /// 递归读取
        /// </summary>
        /// <param name="entities">菜单数据源</param>
        /// <param name="results">结果集</param>
        /// <param name="permissionOperationIds"></param>
        /// <param name="parentId"></param>
        /// <param name="menuCheckedKeys"></param>
        /// <param name="operationCheckedKeys"></param>
        /// <param name="permissionMenuIds"></param>
        private static void GetTreeTableChildren(
            IList<Menu> entities,
            ICollection<TreeTableModel> results,
            ICollection<string> menuCheckedKeys,
            ICollection<string> operationCheckedKeys,
            IReadOnlyCollection<string> permissionMenuIds,
            IReadOnlyCollection<string> permissionOperationIds,
            string parentId = "")
        {
            IList<Menu> result = string.IsNullOrEmpty(parentId)
                ? entities.Where(p => string.IsNullOrEmpty(p.ParentId)).ToList()
                : entities.Where(p => p.ParentId == parentId).ToList();

            var index = 0;
            foreach (var item in result)
            {
                // 操作
                var operationList = item.Operations
                    .Where(p => p.MenuId == item.Id)
                    .OrderBy(p => p.Sort)
                    .Select(p => new CheckboxViewModel
                    {
                        Label = p.Name,
                        Value = p.Id!,
                        Checked = permissionOperationIds.Any(c => c == p.Id)
                    })
                    .ToList();
                foreach (var operation in operationList.Where(p => p.Checked))
                {
                    if (operation.Value != null)
                    {
                        operationCheckedKeys.Add(operation.Value);
                    }
                }

                // 菜单
                var isMenuChecked = permissionMenuIds.Any(c => c == item.Id);
                if (isMenuChecked)
                {
                    menuCheckedKeys.Add(item.Id!);
                }

                var res = new TreeTableModel()
                {
                    Level = string.IsNullOrEmpty(item.ParentPath) ? 0 : item.ParentPath.Split(',').Length,
                    Index = index,
                    MenuType = "菜单",
                    Label = item.Name,
                    MenuIcon = item.Icon,
                    IsInside = item.IsInside,
                    Value = item.Id!,
                    Checked = isMenuChecked,
                    Operations = operationList
                };
                // // 如果没有子项才添加
                // if (isMenuChecked && entities.All(p => p.ParentId != item.Id) && !operationList.Any())
                // {
                //     checkedKeys.Add(item.Id);
                // }

                if (entities.Any(p => p.ParentId == item.Id))
                {
                    res.MenuType = "目录";
                    res.Children = new List<TreeTableModel>();
                    GetTreeTableChildren(
                        entities,
                        res.Children,
                        menuCheckedKeys,
                        operationCheckedKeys,
                        permissionMenuIds,
                        permissionOperationIds,
                        item.Id!
                    );
                }

                if (!results.Any(c => c.Value == res.Value))
                {
                    results.Add(res);
                }

                index++;
            }
        }

        public Task<GetTreeSelectDataByRoleIdResponse> GetTreeSelectDataByVersionAsync(string versionId)
        {
            throw new NotImplementedException();
        }

        public Task<List<MenuViewModel>> GetRoutePathAsync(string userId, List<string> versionIds, bool isRoot = false)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}